package com.sylingd.blog.lib

import android.util.Log
import com.google.gson.JsonElement
import com.google.gson.JsonParser
import com.sylingd.blog.BaseApplication
import okhttp3.*
import org.json.JSONObject
import java.io.IOException
import java.util.*
import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec

object Api {
	private const val key = ""
	private val ua = System.getProperty("http.agent")

	private val keyObj = SecretKeySpec(key.toByteArray(), "HmacSHA256")
	private val hmacObj = Mac.getInstance("HmacSHA256")

	private val mediaType = MediaType.parse("application/json")

	private var AppVersion: Int = 0
	get() {
		if (field == 0) {
			val context = BaseApplication.instance
			field = context.packageManager.getPackageInfo(context.packageName, 0).versionCode
		}
		return field
	}

	init {
		hmacObj.init(keyObj)
	}

	fun call(req: ApiRequest, callback: Callback) {
		val params = req.build()
		val body = RequestBody.create(mediaType, params.param)
		val request = Request.Builder()
				.post(body)
				.addHeader("User-Agent", ua)
				.addHeader("X-Client", "Android")
				.addHeader("X-Version", AppVersion.toString())
				.addHeader("X-Sign", params.sign)
				.url(params.url)
				.build()
		BaseApplication.mOkHttpClient.newCall(request).enqueue(object: okhttp3.Callback {
			override fun onFailure(call: Call?, e: IOException?) {
				callback.onFail(e?.localizedMessage)
			}
			override fun onResponse(call: Call?, response: Response?) {
				if (response != null && response.isSuccessful) {
					val json = response.body()!!.string()
					val data = JsonParser().parse(json).asJsonObject
					if (data.get("success").asInt == 1) {
						//请求成功
						callback.onSuccess(data.get("data"))
					} else {
						callback.onFail(data.get("message").asString)
					}
				} else {
					callback.onFail(response?.message())
				}
			}
		})
	}

	fun createSign(s: String): String {
		val b = hmacObj.doFinal(s.toByteArray())
		val hs = StringBuilder()
		b.forEach {
			val r = Integer.toHexString(0xFF and it.toInt())
			if (r.length == 1)
				hs.append('0')
			hs.append(r)
		}
		return hs.toString().toLowerCase()
	}

	abstract class Callback {
		abstract fun onSuccess(data: JsonElement)
		open fun onFail(message: String?) {
			if (message != null) {
				Log.d("ShuangYa", message)
			}
		}
	}

	class ApiRequest(val action: String) {
		var param: JSONObject = JSONObject()

		fun build(): BuildResult {
			param.put("_t", Date().time)
			val p = param.toString()
			val sign = Api.createSign(p)
			return BuildResult(Config.apiUrl + action + ".json", sign, p)
		}
	}

	class BuildResult(val url: String, val sign: String, val param: String)
}